package org.zn.etl.controller;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.zn.datax.common.entity.ColumnInfo;
import org.zn.datax.common.entity.TableInfo;
import org.zn.etl.datasource.entity.DataSourceInfo;
import org.zn.etl.jdbc.SqlBuilder;
import org.zn.etl.job.entity.BatchJobGroupForm;
import org.zn.etl.job.entity.ColumnMappingForm;
import org.zn.etl.job.entity.DataMapping;
import org.zn.etl.job.entity.EtlJob;
import org.zn.etl.job.entity.JobAnalyseForm;
import org.zn.etl.job.entity.JobGroup;
import org.zn.etl.job.entity.po.DataSourceInfoPo;
import org.zn.etl.job.entity.po.EtlJobPo;
import org.zn.etl.job.entity.po.JobGroupPo;
import org.zn.etl.misc.ResponseInfo;
import org.zn.etl.service.EtlAnalyseService;
import org.zn.etl.service.EtlPersistService;

@RequestMapping("/etl/manage")
@RestController
public class EtlManagerController {
	
	@Autowired
	private EtlPersistService  etlPersistService;
	
	@Autowired
	private EtlAnalyseService analyseService ;
	
	/**
	 * 添加 数据源
	 * @param dsi
	 * @return
	 */
	@PostMapping("dataSource")
	public   ResponseInfo<DataSourceInfoPo>  addDataSource(@RequestBody DataSourceInfo dsi) {
	
		DataSourceInfoPo po= etlPersistService.addDataSourceInfo(dsi);

		return ResponseInfo.success(po);
	}
	
	@PutMapping("dataSource")
	public ResponseInfo<DataSourceInfoPo>  updateDataSource(@RequestBody DataSourceInfoPo dsi) {
	
		etlPersistService.updateDataSourceInfo(dsi);

		return ResponseInfo.success(dsi) ;
	}
	
	
	
	/**
	 * 查询数据源
	 * @param name
	 * @return
	 */
	@GetMapping("dataSource/{name}")
	public  ResponseInfo<DataSourceInfoPo>  dataSourceByName(@PathVariable("name") String name) {
		DataSourceInfoPo po= etlPersistService.queryDataSourceByName(name);
		return ResponseInfo.success(po);
	}
	
	/**
	 * 数据源列表
	 * @param page
	 * @param size
	 * @return
	 */
	@GetMapping("dataSource/list")
	public  ResponseInfo<List<DataSourceInfoPo>>  dataSourceByNameList(Integer page,Integer size) {
		List<DataSourceInfoPo> list= etlPersistService.dataSourceList(page,size);
		return ResponseInfo.success(list);
	}
	
	/**
	 * 任务列表
	 * @param page
	 * @param size
	 * @return
	 */
	@GetMapping("job/list")
	public  ResponseInfo<List<EtlJobPo>>  jobList(Integer page,Integer size) {
		List<EtlJobPo> list= etlPersistService.queryEtlJobList(page,size);
		return  ResponseInfo.success(list);
	}
	
	/**
	 * 名称查询任务
	 * @param name
	 * @return
	 */
	@GetMapping("job/{name}")
	public  ResponseInfo<EtlJob>  jobList(@PathVariable() String name) {
		EtlJob list= etlPersistService.queryEtlJob(name);
		return  ResponseInfo.success(list) ;
	}
	
	/**
	 * 添加任务
	 * @param job
	 * @return
	 */
	@PostMapping("job")
	public ResponseInfo<EtlJobPo>  saveJob(@RequestBody EtlJob job) {
		
		boolean hasDm=Objects.nonNull(job.getDataMappings());
		
		if(hasDm) {
			
		DataMapping dm = job.getDataMappings().get(0);

		List<Pair<ColumnInfo, ColumnInfo>> columnMappingPairs = new ArrayList<>();
		TableInfo st = dm.getSourceTable();
		TableInfo tt = dm.getTargetTable();

		if ("oracle".equals(dm.getWapperPaged())) {
			dm.setSourceSql(SqlBuilder.oracleSubSeclt(dm.getSourceSql()));
		}
		if (ArrayUtils.isNotEmpty(st.getColumns())) {
			for (int i = 0; i < st.getColumns().length; i++) {
				ColumnInfo l = st.getColumns()[i];
				ColumnInfo r = tt.getColumns()[i];
				columnMappingPairs.add(Pair.of(l, r));
			}
		}
		dm.setColumnMappingPairs(columnMappingPairs);
		}
		
		

		if(Objects.isNull(job.getId()) && Objects.isNull(job.getAvailable()))job.setAvailable(1);
		
		EtlJobPo po = etlPersistService.saveEtlJob(job);
		
		if(hasDm) {
		try {
			analyseService.analyseJob(JobAnalyseForm.builder().jobName(job.getJobName()).merge(true).missMatchColumn("ignore").build());
		} catch (Exception e) {
			e.printStackTrace();
		}
		}
		return ResponseInfo.success(po) ;
	}
	
	
	
	
	
	/**
	 * 添加组
	 * @param job
	 * @return
	 */
	@PostMapping("group")
	public ResponseInfo<JobGroupPo>  addJobToGroup(@RequestBody JobGroup job) {
		JobGroupPo po= etlPersistService.addJobGroup(job);
		return  ResponseInfo.success(po);
	}
	
	
	/**
	 * 批量添加 job 至组
	 * @param job
	 * @return
	 */
	@PostMapping("job/group")
	public ResponseInfo<JobGroupPo>  batchAddJobForGroup(@RequestBody BatchJobGroupForm form) {
		JobGroupPo po= etlPersistService.batchAddJobForGroup(form);
		return ResponseInfo.success(po);
	}
	
	/**
	 * 任务组列表
	 * @param page
	 * @param size
	 * @return
	 */
	@GetMapping("group/list")
	public  ResponseInfo< List<JobGroupPo>>  jobGroupList(Integer page,Integer size) {
		
		if(page==null)page=1;
		if(size==null)size=10;
		
		 List<JobGroupPo> list= etlPersistService.jobGroupList(page, size);
		return ResponseInfo.success(list);
	}
	
	/**
	 * 任务添加 列映射
	 * @param form
	 * @return
	 */
	@PostMapping("job/column/mapping")
	public  ResponseInfo<Integer>  addColumnMapping(@RequestBody ColumnMappingForm form) {

		Integer size= etlPersistService.addDataMappingColumn(form);
		
		return ResponseInfo.success(size);
	}
	
	/**
	 * 删除任务
	 * @param name
	 * @param id
	 * @return
	 */
	@DeleteMapping("job")
	public  ResponseInfo<Integer> delJob(String name,Long id) {
		
		Integer i= etlPersistService.delEtlJob(id, name);
		return  ResponseInfo.success(i);
		
	}
	
	
	/**
	 * 删除列映射
	 * @param jobName
	 * @return
	 */
	@DeleteMapping("clear/job/columnMapping")
	public  ResponseInfo<Integer> delJob(String jobName) {
		
		Integer i= etlPersistService.clearColumnMappingByJobName(jobName);
		return ResponseInfo.success(i);
		
	}
	
	
	
	
	
	

}
